import { login, logout, getInfo } from "@/api/login";
import { staticRoutes, allAsyncRoutes, anyRoute } from "@/router/routes";
import cloneDeep from "lodash/cloneDeep";
import router from "@/router";
import { resetRouter } from "@/router";

function filterAsyncRoutes(allAsyncRoutes, routeNames) {
  return allAsyncRoutes.filter((item) => {
    // 只能过滤出一级路由，二级路由我们是没有过滤过，直接全部拿走，这样不对
    // 所以我们还要对二级路由再次进行过滤，要用递归
    if (routeNames.indexOf(item.name) !== -1) {
      // 过滤出二级路由
      if (item.children && item.children.length > 0) {
        // 下面就过滤出用户想要的二级路由数组，把原本的覆盖掉
        // 这行代码会出现一个bug，它会把allAsyncRoutes路由数组里面的二级路由数组给换
        // 成过滤出来的新数组地址，导致整个二级路由发生变化
        // 所以后期我们在过滤的时候，要深拷贝一份，再去过滤
        item.children = filterAsyncRoutes(item.children, routeNames);
      }
      return true;
    }
  });
}

// 这个函数是专门往路由器内部去动态添加注册路由用的
function addRoutes(routes) {
  // 下面这个方法是vue-router给我们的api,但是缺陷是每次只能添加一个路由对象
  // 所以我们封装方法，去一次添加一个数组所有路由
  router.addRoutes(routes); //每次只能添一个
}

// 这个函数是专门用于重置路由的
function resetRoutes(staticRoutes) {
  // 1、先删除路由器当中注册的所有路由
  let routes = router.getRoutes(); //获取路由器当中的所有路由组成的数组
  routes.forEach((item) => {
    if (item.name) {
      router.removeRoute(item.name);
    }
  });
  // 2、再把路由器当中动态添加静态路由
  addRoutes(staticRoutes);
}

const state = {
  token: localStorage.getItem("token_key") || "",
  userInfo: {},
  menuRoutes: [],
};

const mutations = {
  SET_TOKEN: (state, token) => {
    state.token = token;
  },
  SET_USERINFO(state, userInfo) {
    state.userInfo = userInfo;
  },
  RESET_USERINFO(state) {
    state.userInfo = {};
    state.token = "";
  },
};

const actions = {
  // user login
  async login({ commit }, loginParams) {
    try {
      const result = await login(loginParams);
      commit("SET_TOKEN", result.data.token);
      localStorage.setItem("token_key", result.data.token);
      return "ok";
    } catch (error) {
      return Promise.reject(new Error("获取失败"));
    }
  },

  // get user info
  async getUserInfo({ commit }) {
    try {
      const result = await getInfo();
      commit("SET_USERINFO", result.data);
      let userAsyncRoutes = filterAsyncRoutes(
        cloneDeep(allAsyncRoutes),
        result.data.routes
      );
      // return;
      userAsyncRoutes.push(anyRoute);
      router.addRoutes(userAsyncRoutes);

      router.options.routes = staticRoutes.concat(userAsyncRoutes);

      return "ok";
    } catch (error) {
      return Promise.reject(new Error("获取用户信息失败"));
    }
  },

  // user logout
  async logout({ commit }) {
    try {
      const result = await logout();

      if (result.code === 20000) {
        //清空token
        //清空用户信息

        localStorage.removeItem("token_key");
        commit("RESET_USERINFO");

        // 重置路由器，把路由器当中注册的路由再换成staticRoutes
        // resetRoutes(staticRoutes);
        resetRouter();

        return "ok";
      } else {
        return Promise.reject(new Error("failed"));
      }
    } catch (error) {
      return Promise.reject(new Error("failed"));
    }
  },
  // // remove token
  resetToken({ commit }) {
    // console.log("清空token");
    return new Promise((resolve) => {
      //清空之后直接跳转登录界面   下面是清空之后刷新页面 刷新页面没有token自然也就跳转登录界面了
      this.token = "";
      localStorage.removeItem("token_key");
      location.reload();

      resolve();
    });
  },
};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
};
